Imports System.Net.Mail
Imports System.IO


Namespace Workflow

    Partial Class EditItem : Inherits System.Web.UI.Page

#Region " Web Form Designer Generated Code "

        'This call is required by the Web Form Designer.
        <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

        End Sub


        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
            'CODEGEN: This method call is required by the Web Form Designer
            'Do not modify it using the code editor.
            InitializeComponent()
        End Sub

#End Region

#Region "Properties"
        Private ReadOnly Property ItemId() As Integer
            Get
                Return Request.QueryString("itemId")
            End Get
        End Property
        Private _item As CItem
        Private ReadOnly Property Item() As CItem
            Get
                If IsNothing(_item) Then
                    If ItemId > 0 Then
                        _item = CItem.Cache.GetById(ItemId)
                    Else
                        _item = New CItem
                        _item.ItemDateCreated = DateTime.Now
                        _item.ItemCreatedByUserId = CSession.UserId
                        _item.ItemStatusId = CConfig.StatusNotStarted
                    End If
                End If
                Return _item
            End Get
        End Property
        Private ReadOnly Property DeleteItemId() As Integer
            Get
                Return Request.QueryString("deleteItemId")
            End Get
        End Property
        Private ReadOnly Property DeleteFileId() As Integer
            Get
                Return Request.QueryString("deleteFileId")
            End Get
        End Property
        Private ReadOnly Property DeleteCommentId() As Integer
            Get
                Return Request.QueryString("deleteCommentId")
            End Get
        End Property

#End Region

#Region "Event Handlers"
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            If Page.IsPostBack Then Exit Sub


            If IsNothing(Item) Then Response.Redirect("~/pages/listitems.aspx")
            If ItemId > 0 Then Title = "Job #" & ItemId & ": " & Item.ItemName

            If DeleteFileId > 0 Then
                With CFile.Cache.GetById(DeleteFileId)
                    If IO.File.Exists(FolderPath() & .FileName) Then IO.File.Delete(FolderPath() & .FileName)
                    .Delete()
                End With
                Response.Redirect("EditItem.aspx?itemId=" & ItemId, True)
            End If
            If DeleteItemId > 0 Then
                Dim l As CLink = CLink.Cache.GetById(ItemId, DeleteItemId)
                If Not IsNothing(l) Then
                    l.Delete()
                Else
                    l = CLink.Cache.GetById(DeleteItemId, ItemId)
                    If Not IsNothing(l) Then l.Delete()
                End If
                Response.Redirect("EditItem.aspx?itemId=" & ItemId, True)
            End If
            If DeleteCommentId > 0 Then
                With CComment.Cache.GetById(DeleteCommentId)
                    .Delete()
                End With
                Response.Redirect("EditItem.aspx?itemId=" & ItemId, True)
            End If

            rblPriority.DataSource = CPriority.Cache
            rblPriority.DataBind()
            rblPriority.SelectedIndex = 1

            ddCategory.DataSource = CCategory.Cache
            ddCategory.DataBind()
            ddCategory.SelectedIndex = 0

            ddUserId.DataSource = CUser.Cache
            ddUserId.DataBind()
            ddUserId.Items.Insert(0, New ListItem("-- Unassigned --", Integer.MinValue))
            CUtilities.SetValue(ddUserId, CSession.UserId)

            ddUserId2.DataSource = CUser.Cache
            ddUserId2.DataBind()
            ddUserId2.Items.Insert(0, New ListItem("", Integer.MinValue))

            ddUserId3.DataSource = CUser.Cache
            ddUserId3.DataBind()
            ddUserId3.Items.Insert(0, New ListItem("", Integer.MinValue))

            ddUserId4.DataSource = CUser.Cache
            ddUserId4.DataBind()
            ddUserId4.Items.Insert(0, New ListItem("", Integer.MinValue))

            ddCc.DataSource = CUser.Cache
            ddCc.DataBind()
            ddCc.ToolTip = "Use the CTRL key to select multiple jobs"

            'CUtilities.OnReturnPress(txtComments, btnAddComment)
            'CUtilities.OnReturnPress(txtDescription, btnSave)
            CUtilities.OnReturnPress(txtIssue, btnAdd)
            CUtilities.OnReturnPress(txtEstimate, btnSave)
            'CUtilities.OnReturnPress(txtName, btnSave)


            rowStatus.Visible = ItemId > 0
            If ItemId <= 0 Then
                Try
                    If CSession.LastPriority > 0 Then rblPriority.SelectedValue = CSession.LastPriority
                    If CSession.LastCategoryId > 0 Then ddCategory.SelectedValue = CSession.LastCategoryId
                Catch ex As Exception
                End Try
                btnSave.Text = "Add Job"
                btnDelete.Enabled = False
                lnkNew.Visible = False
                Exit Sub
            End If

            litTitle.Text = "Job #" & ItemId
            With Item
                txtDescription.Text = .ItemDescription
                txtName.Text = .ItemName
                txtEstimate.Text = .ItemEstimatedHours
                ddCategory.SelectedValue = .ItemCategoryId
                rblPriority.SelectedValue = .ItemPriorityId
                ddUserId.SelectedValue = .ItemAssignedToUserId
                ddUserId2.SelectedValue = .ItemAssignedToUserId2
                ddUserId3.SelectedValue = .ItemAssignedToUserId3
                ddUserId4.SelectedValue = .ItemAssignedToUserId4

                litStatusName.Text = .StatusName

                dgHistory.DataSource = .Historys
                dgHistory.DataBind()

                dgComments.DataSource = .Comments
                dgComments.DataBind()
                dgComments.Visible = dgComments.Items.Count > 0

                dgFiles.DataSource = .Files
                dgFiles.DataBind()
                dgFiles.Visible = dgFiles.Items.Count > 0

                dgIssues.DataSource = .RelatedItems
                dgIssues.DataBind()
                dgIssues.Visible = dgIssues.Items.Count > 0

                Select Case .ItemStatusId
                    Case CConfig.StatusNotStarted
                        btnStart.Visible = True
                        btnFinish.Visible = True
                    Case CConfig.StatusInProgress
                        btnStop.Visible = True
                        btnFinish.Visible = True
                    Case CConfig.StatusComplete
                        btnOpen.Visible = True
                End Select
            End With
        End Sub

        Private Sub btnAddComment_Click(ByVal sender As System.Object, ByVal e As ImageClickEventArgs) Handles btnAddComment.Click
            Save()

            With New CComment
                .CommentDate = DateTime.Now
                .Comment = txtComments.Text
                .CommentItemId = Item.ItemId
                .CommentUserId = User.Identity.Name
                .Save()
            End With

            Response.Redirect("EditItem.aspx?itemId=" & Item.ItemId, True)
        End Sub
        Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click
            Item.Delete()
            Response.Redirect("ListItems.aspx", True)
        End Sub
        Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
            Dim assigned As Boolean = Save(True)
            SendEmails(assigned, Item)

            If sender Is btnSave Or sender Is btnFinish Then
                Response.Redirect("ListItems.aspx", True)
            Else
                Response.Redirect("EditItem.aspx?itemId=" & ItemId, True)
            End If
        End Sub
        Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnAdd.Click
            If txtIssue.Text.Length = 0 Then Exit Sub
            Dim linkToId As Integer = Integer.Parse(txtIssue.Text)
            If linkToId = Me.ItemId Then Exit Sub

            Save()

            With New CLink
                .LinkFromItemId = Item.ItemId
                .LinkToItemId = Integer.Parse(txtIssue.Text)
                Try
                    .Save()
                Catch ex As Exception
                    CUtilities.ScriptPopup(Page, ex.Message)
                    Exit Sub
                End Try
                txtIssue.Text = ""
            End With

            Response.Redirect("EditItem.aspx?itemId=" & Item.ItemId, True)
        End Sub
        Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As ImageClickEventArgs) Handles btnUpload.Click
            Save()

            Dim upload As HttpPostedFile = Request.Files(0)
            If upload.ContentLength = 0 Then Exit Sub

            Dim originalFileName As String = Path.GetFileName(upload.FileName)
            Dim uniqueFileName As String = originalFileName
            Dim filePath As String = FolderPath() & originalFileName
            While File.Exists(filePath)
                uniqueFileName = UniqueName(uniqueFileName)
                filePath = FolderPath() & uniqueFileName
            End While

            If Not Directory.Exists(FolderPath) Then
                Directory.CreateDirectory(FolderPath)
            End If

            With New CFile
                .FileItemId = Item.ItemId
                .FileMimeType = upload.ContentType
                .FileName = uniqueFileName
                .FileSize = upload.ContentLength
                .Save()
                upload.SaveAs(filePath)
            End With

            Response.Redirect("EditItem.aspx?itemId=" & Item.ItemId, True)
        End Sub
        Private Sub btnAddProject_Click(ByVal sender As System.Object, ByVal e As ImageClickEventArgs) Handles btnAddProject.Click
            With New CCategory
                .CategoryName = hiddenProjectName.Value
                .Save()

                ddCategory.DataSource = CCategory.Cache
                ddCategory.DataBind()
                ddCategory.SelectedValue = .CategoryId
            End With
        End Sub

        'State transitions
        Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
            If ddUserId.SelectedIndex <= 0 Then ddUserId.SelectedValue = CSession.UserId
            Item.ItemStatusId = CConfig.StatusInProgress
            Item.ItemDateStarted = DateTime.Now
            btnSave_Click(sender, e)
        End Sub
        Private Sub btnFinish_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFinish.Click
            With Item
                .ItemStatusId = CConfig.StatusComplete
                .ItemDateCompleted = DateTime.Now
            End With
            btnSave_Click(sender, e)
        End Sub
        Protected Sub btnOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpen.Click
            Item.ItemStatusId = CConfig.StatusInProgress
            btnSave_Click(sender, e)
        End Sub
        Protected Sub btnStop_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnStop.Click
            Item.ItemStatusId = CConfig.StatusNotStarted
            btnSave_Click(sender, e)
        End Sub
#End Region

#Region "Functions"
        Public Function Save(Optional ByVal saveButton As Boolean = False) As Boolean
            If txtEstimate.Text.Length = 0 Then txtEstimate.Text = "0"

            With Item
                .ItemAssignedToUserId = ddUserId.SelectedValue
                .ItemAssignedToUserId2 = ddUserId2.SelectedValue
                .ItemAssignedToUserId3 = ddUserId3.SelectedValue
                .ItemAssignedToUserId4 = ddUserId4.SelectedValue
                .ItemCategoryId = ddCategory.SelectedValue
                .ItemDescription = txtDescription.Text
                .ItemName = txtName.Text
                .ItemEstimatedHours = Framework.CTextbox.GetNumber(txtEstimate)
                .ItemPriorityId = rblPriority.SelectedValue

                If ItemId <= 0 Then
                    CSession.LastPriority = .ItemPriorityId
                    CSession.LastCategoryId = .ItemCategoryId
                End If
            End With

            Dim assigned As Boolean = False
            If ItemId > 0 Then
                Dim before As CItem = CItem.Cache.GetById(ItemId)
                Item.Save()

                Dim changes As String = CompareChanges(before, Item)
                If Len(changes) = 0 Then
                    If saveButton AndAlso Not chkSendEmail.Checked Then Response.Redirect("ListItems.aspx", True)
                    Return False
                End If
                With New CHistory
                    .HistoryItemId = Item.ItemId
                    .HistoryUserId = User.Identity.Name
                    .HistoryDescription = changes
                    .Save()
                End With

                assigned = before.ItemAssignedToUserId <> Item.ItemAssignedToUserId
            Else
                Item.Save()

                assigned = Item.ItemAssignedToUserId > 0

                With New CHistory
                    .HistoryItemId = Item.ItemId
                    .HistoryUserId = User.Identity.Name
                    .HistoryDescription = "Created"
                    .Save()
                End With
            End If

            Return assigned
        End Function
        Public Function CompareChanges(ByVal a As CItem, ByVal b As CItem) As String
            Dim s As String = String.Empty
            If a.AssignedToNames_ <> b.AssignedToNames_ Then s &= FormatChange("Assigned To", a.AssignedToNames_, b.AssignedToNames_)
            If a.ItemCategoryId <> b.ItemCategoryId Then s &= FormatChange("Category", a.CategoryName, b.CategoryName)
            If a.ItemName <> b.ItemName Then s &= FormatChange("Title", a.ItemName, b.ItemName)
            If a.ItemDescription <> b.ItemDescription Then s &= FormatChange("Description", a.ItemDescription, b.ItemDescription)
            If a.ItemEstimatedHours <> b.ItemEstimatedHours Then s &= FormatChange("Est.Hrs", a.ItemEstimatedHours, b.ItemEstimatedHours)
            If a.ItemPriorityId <> b.ItemPriorityId Then s &= FormatChange("Priority", a.PriorityName, b.PriorityName)
            If a.ItemStatusId <> b.ItemStatusId Then s &= FormatChange("Status", a.StatusName, b.StatusName)
            If Len(s) > 0 Then Return s.Substring(0, s.Length - 2)
            Return s
        End Function
        Public Function FormatChange(ByVal title As String, ByVal a As String, ByVal b As String) As String
            Return title & ": '" & a & "' => '" & b & "'" & vbCrLf
        End Function
        Public Sub SendEmails(ByVal assigned As Boolean, ByVal item As CItem)
            If Not chkSendEmail.Checked Then Exit Sub

            Dim subject As String = "Job #" & item.ItemId & " has been "
            If assigned Then subject &= "assigned to you" Else subject &= "updated"

            Dim ccList As String = ""
            Dim i As ListItem, usr As CUser
            For Each i In ddCc.Items
                If True = i.Selected Then
                    usr = CUser.Cache.GetById(i.Value)
                    ccList &= FormatEmail(usr.UserName, usr.UserEmail) & ";"
                End If
            Next

            Dim mail As New MailMessage
            If ddUserId.SelectedIndex > 0 Then
                mail.To.Add(New MailAddress(item.AssignedTo1.UserEmail, item.AssignedTo1.UserName))
                If Not IsNothing(item.AssignedTo2) Then
                    mail.To.Add(New MailAddress(item.AssignedTo2.UserEmail, item.AssignedTo2.UserName))
                End If
                If Not IsNothing(item.AssignedTo3) Then
                    mail.To.Add(New MailAddress(item.AssignedTo3.UserEmail, item.AssignedTo3.UserName))
                End If
            Else
                If ccList.Length = 0 Then Exit Sub
                mail.To.Add(ccList)
                ccList = ""
            End If

            Dim sender As CUser = CUser.Cache.GetById(User.Identity.Name)

            mail.Subject = subject
            If ccList.Length > 0 Then mail.CC.Add(ccList)

            mail.Body = MailBody(item, sender, subject)
            mail.IsBodyHtml = True
            mail.From = New MailAddress(sender.UserEmail, sender.UserName)

            'Try
            '    'Regular smtp
            '    With New SmtpClient
            '        .Host = CConfig.SmtpServer
            '        .Send(mail)
            '    End With
            'Catch

            'Gmail (special ports)
            Try
                With CConfig.GmailOnPort1
                    .Send(mail)
                End With
            Catch
                'try the other port
                With CConfig.GmailOnPort2
                    .Send(mail)
                End With
            End Try

            'End Try
        End Sub
        Private Function FormatEmail(ByVal name As String, ByVal email As String) As String
            Return name & "<" & email & ">"
        End Function
        Private Function MailBody(ByVal item As CItem, ByVal sender As CUser, ByVal subject As String) As String
            Dim url As String = Request.Url.AbsoluteUri
            If -1 = url.IndexOf("?") Then url &= "?itemId=" & item.ItemId

            Dim body As New CTemplate("mail.htm", "~/templates/")
            body.Replace("subject", subject)
            body.Replace("name", item.ItemName)
            body.Replace("description", item.ItemDescription)
            body.Replace("sender", sender.UserName)
            body.Replace("assignedTo", item.AssignedToNames_)
            'body.Replace("history", ShowHistory(item))
            body.Replace("url", url)
            Return body.Template
        End Function
        Public Function ShowHistory(ByVal item As CItem) As String
            Dim html As New CTemplate("history.htm", "~/templates/")
            Dim s As New StringBuilder()
            For Each i As CHistory In item.Historys
                html.Reset()
                html.Replace("date", i.HistoryDate.ToString("dd MMM yyyy HH:mm:ss"))
                html.Replace("user", i.User.UserName)
                html.Replace("description", i.HistoryDescriptionBr)
                s.Append(html.Template)
            Next
            Return s.ToString
        End Function
        Public Shared Function FolderPath() As String
            Return HttpContext.Current.Server.MapPath("~/files/")
        End Function
        Private Shared Function UniqueName(ByVal name As String) As String
            Dim extension As String = Path.GetExtension(name)
            Dim baseName As String = name.Substring(0, name.LastIndexOf(extension))

            If 0 = baseName.Length Then Return "_" & name 'trivial case

            Dim len As Integer = baseName.Length
            Dim suffix As String = "(" & 1 & ")" & extension
            If ")" <> baseName.Substring(len - 1, 1) Then Return baseName & suffix

            Dim startAt As Integer = baseName.LastIndexOf("(")
            If -1 = startAt Then Return baseName + suffix

            Dim number As String = baseName.Substring(startAt + 1, len - startAt - 2)
            Try
                Dim nextNumber As Integer = Integer.Parse(number) + 1
                Return baseName.Substring(0, startAt) + "(" + nextNumber.ToString() + ")" + extension
            Catch
                Return baseName + suffix
            End Try
        End Function
#End Region

    End Class

End Namespace
